/******************************************************************************

   REBVO: RealTime Edge Based Visual Odometry For a Monocular Camera.
   Copyright (C) 2016  Juan José Tarrio
   
   Jose Tarrio, J., & Pedre, S. (2015). Realtime Edge-Based Visual Odometry
   for a Monocular Camera. In Proceedings of the IEEE International Conference
   on Computer Vision (pp. 702-710).
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA

 *******************************************************************************/

#ifndef CIRCLIST_H
#define CIRCLIST_H

#include <stdexcept>
namespace  rebvo{
namespace util{

//CircListIndexer: simple class to index circular buffers

class CircListIndexer{

    int inx;
    int num;
    uint size;

public:

    CircListIndexer(uint list_size) : inx(0),num(0),size(list_size){}
    CircListIndexer(int index,int numelem,uint list_size) : inx(index),num(numelem),size(list_size){}

    CircListIndexer operator+(const int &r){
        return CircListIndexer((inx+(r%size)+size)%size,num,size);
    }

    CircListIndexer operator-(const int &r){
        return CircListIndexer((inx-(r%size)+size)%size,num,size);
    }

    CircListIndexer& operator++(){

        inx=(inx+1)%size;

        return *this;
    }


    CircListIndexer& operator--(){

        inx=(inx-1+size)%size;

        return *this;
    }

    CircListIndexer& operator+=(const int &r){

        inx=(inx+(r%size)+size)%size;

        return *this;
    }


    CircListIndexer& operator-=(const int &r){

        inx=(inx-(r%size)+size)%size;

        return *this;
    }

    operator int()
    {
        return inx;
    }

    CircListIndexer& AddOne(){
        if(num<size)
            num++;
        inx=(inx+1)%size;
        return *this;
    }

    const int& NumElem(){
        return num;
    }


    uint Size(){
        return size;
    }

     bool operator==(const CircListIndexer& rhs){
         return inx==rhs.inx;
     }


};




}
}
#endif // CIRCLIST_H
